package com.jingxuan.config;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

/**
 * Jackson配置类
 * 用于处理 HTTP 请求/响应中的时间序列化和反序列化
 */
@Configuration
public class JacksonConfig {

    /**
     * 自定义 LocalDateTime 反序列化器
     * 支持带时区的字符串，自动转换为 Asia/Shanghai 时区的 LocalDateTime
     */
    public static class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
        private static final long serialVersionUID = 1L;
        private static final ZoneId TARGET_ZONE = ZoneId.of("Asia/Shanghai");

        public LocalDateTimeDeserializer() {
            super(LocalDateTime.class);
        }

        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String dateStr = p.getText().trim();
            if (dateStr == null || dateStr.isEmpty()) {
                return null;
            }

            try {
                // 首先尝试解析为带时区的 ZonedDateTime（ISO 8601 格式）
                // 格式: 2025-11-03T09:11:33+08:00 或 2025-11-03T09:11:33-05:00 或 2025-11-03T09:11:33Z
                if (dateStr.contains("T") && (dateStr.contains("+") || dateStr.contains("-") || dateStr.endsWith("Z"))) {
                    // 查找时区偏移的位置（在T之后的时间部分）
                    int tIndex = dateStr.indexOf('T');
                    if (tIndex > 0) {
                        String timePart = dateStr.substring(tIndex + 1);
                        // 检查是否包含时区偏移（+HH:mm 或 -HH:mm 或 Z）
                        if (timePart.matches(".*[+-]\\d{2}:\\d{2}$") || timePart.endsWith("Z")) {
                            try {
                                // 解析为 ZonedDateTime
                                ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
                                // 转换为目标时区（Asia/Shanghai）的 LocalDateTime
                                return zonedDateTime.withZoneSameInstant(TARGET_ZONE).toLocalDateTime();
                            } catch (Exception e) {
                                // 如果 ISO_OFFSET_DATE_TIME 解析失败，尝试其他方式
                            }
                        }
                    }
                }
                
                // 尝试解析不带时区的 LocalDateTime
                // 格式: 2025-11-03T09:11:33 或 2025-11-03 09:11:33
                if (dateStr.contains("T")) {
                    // 移除可能的时区后缀
                    String cleaned = dateStr.replaceAll("[+-]\\d{2}:?\\d{0,2}$", "")
                                           .replaceAll("Z$", "")
                                           .trim();
                    return LocalDateTime.parse(cleaned, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));
                } else {
                    // 格式: 2025-11-03 09:11:33
                    return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                }
            } catch (Exception e) {
                throw new IOException("无法解析时间字符串: " + dateStr + ", 错误: " + e.getMessage(), e);
            }
        }
    }

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper mapper = builder.build();
        
        // 设置时区
        mapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        
        // 注册 JavaTimeModule
        mapper.registerModule(new JavaTimeModule());
        
        // 禁用时间戳格式
        mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        
        // 注册自定义 LocalDateTime 反序列化器
        SimpleModule module = new SimpleModule();
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        mapper.registerModule(module);
        
        return mapper;
    }
}

